using System;
using System.Collections;
using System.Collections.Generic;
using Edge.Business.Entities;
using Edge.Business.Security;
using Edge.Common;
using Edge.Common.ComponentModel.Notification;
using Edge.Common.Services;
using Edge.Common.Utils;
using Edge.DAL.Common;
using Edge.DAL.Managers;
using NHibernate;
using NHibernate.Expression;
using NHibernate.SqlCommand;
using NHibernate.Transform;
using NHibernate.Type;
using Shop.Business.Domain.Catalog;
using Shop.Business.Domain.Customers;

namespace Shop.DAL.Managers
{
    class ProductGroupManager : AbstractManager<ProductGroup, int, Customer>, IProductGroupManager
    {
        public ICollection<ProductGroup> Find(FetchOptions fetchOptions, ProductGroupFilter filter)
        {
            ICriteria criteria = CreateCriteria(fetchOptions);
            AddRestrictions(criteria, filter);
            return criteria.List<ProductGroup>();
        }

        public int Count(ProductGroupFilter filter)
        {
            ICriteria criteria = CreateCriteria();
            AddRestrictions(criteria, filter);
            criteria.SetProjection(Projections.RowCount());
            return (int)criteria.List()[0];
        }

        private void AddRestrictions(ICriteria criteria, ProductGroupFilter filter)
        {
//            if (!StringUtils.IsBlankOrNull(filter.UserID))
//                criteria.Add(Expression.Eq("Customer.Id", Convert.ToInt32(filter.UserID)));
            if (!StringUtils.IsBlankOrNull(filter.GetText()) && !(filter.GetText().Trim().Equals("")) && !filter.IsBrandArt)
            {
                criteria.Add(Expression.Disjunction()
                                 .Add(Expression.Like("Name", "%" + filter.GetText().Trim() + "%"))
                                 .Add(Expression.Like("Description", "%" + filter.GetText().Trim() + "%"))
                    );
            }
            if (filter.IsBrandArt || !StringUtils.IsBlankOrNull(filter.BrandArt))
            {
                criteria.CreateAlias("Products", "prod", JoinType.LeftOuterJoin);
                if (!StringUtils.IsBlankOrNull(filter.BrandArt))
                {
                    criteria.Add(Expression.Eq("prod.BrandArt", filter.BrandArt));
                }
                else
                {
                    criteria.Add(Expression.Like("prod.BrandArt", filter.GetText().Trim() + "%"));
                }
                criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());

            }

            if (!StringUtils.IsBlankOrNull(filter.SizeIds))
            {
                criteria.CreateAlias("SizeValues", "sizes", JoinType.LeftOuterJoin);
                var array = filter.SizeIds.Substring(1).Split(',');
                Disjunction disjunction = Expression.Disjunction();
                for (int i = 0; i < array.Length; i++)
                {
                    disjunction.Add(Expression.Like("sizes.Value", "%" + array[i] + "%"));
                }
                criteria.Add(disjunction);
                
                if (filter.InStock)
                {
                    criteria.Add(Expression.Between("sizes.Qty", 1,100));
                }
                criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());

            }
            
            if (!filter.ShowInVis)
                criteria.Add(Expression.Eq("Visible",filter.Visible));
            if (filter.InStock)
                criteria.Add(Expression.Between("Qty", 1, 100));
            if (!StringUtils.IsBlankOrNull(filter.CatIds))
            {
                var array = filter.CatIds.Substring(1).Split(',');
                ArrayList list = new ArrayList();
                foreach (string s in array)
                {
                    Category category = Locator.GetService<ICategoryManager>().Load(Convert.ToInt32(s));
                    if (category != null && category.Children != null)
                    {
                        foreach (Category child in category.Children)
                        {
                            if (!filter.CatIds.Contains(child.Id.ToString()) && !list.Contains(child.Id.ToString()))
                                list.Add(child.Id.ToString());
                            if (child.Children!= null)
                            {
                                foreach (Category child2 in child.Children)
                                {
                                    if (!filter.CatIds.Contains(child2.Id.ToString()) && !list.Contains(child.Id.ToString()))
                                        list.Add(child2.Id.ToString());
                                }
                            }
                        }
                    }
                    list.Add(s);
                }

                criteria.Add(Expression.In("Category.Id", list));
            }
//            if (filter.Brand != null)
//                criteria.Add(Expression.Eq("Brand", filter.Brand));
            if (!StringUtils.IsBlankOrNull(filter.BrandIds))
            {
                var array = filter.BrandIds.Substring(1).Split(',');
                criteria.Add(Expression.In("Brand.Id",array));
            }
            if (filter.GroupStatus != null)
                criteria.Add(Expression.Eq("GroupStatus", filter.GroupStatus));


        }

    }
}
